package utils

import (
	"admin100/library/define"
	"admin100/library/define/defErr"
	"encoding/json"
	"fmt"
	"reflect"

	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
)

var ids = Ids{
	Id:  0,
	Uid: "",
}

type Ids struct {
	Id  int
	Uid string
}
type P struct {
	IdArr Ids
	Name  string
	Age   int
	Sli   []int
}

func Marshal(data interface{}) []byte {
	if data == nil {
		return nil
	}
	r, err := json.Marshal(data)
	if err != nil {
		defErr.Panic(define.Fail, err.Error())
	}

	return r
}

func Unmarshal(data []byte, v *interface{}) {
	err := json.Unmarshal(data, v)
	if err != nil {
		defErr.Panic(define.Fail, err.Error())
	}
}

// 将结果数据叶值转为字符串
func ResConvertStr() {
	uid := ids.Uid
	fmt.Println(uid)
	p := P{
		IdArr: Ids{
			Id:  2,
			Uid: "435",
		},
		Name: "ss",
		Age:  9,
		Sli:  []int{6, 7, 8},
	}
	data := gconv.Map(p)
	g.Dump(MapAllValueToStr(data))
}

//
func MapAllValueToStr(origin interface{}) interface{} {

	v := reflect.ValueOf(&origin)

	for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
		v = v.Elem()
	}

	switch v.Kind() {
	case reflect.Slice:
		// slice里的值不进行处理，保留原值
	case reflect.Map:
		for _, key := range v.MapKeys() {
			ret := v.MapIndex(key).Interface()
			v.SetMapIndex(key, reflect.ValueOf(MapAllValueToStr(ret)))
		}
	case reflect.Struct:
		return MapAllValueToStr(gconv.Map(origin))
	default:
		return fmt.Sprintf("%v", origin)
	}

	return origin
}

// 切片去重
func RemoveRedata(s []string) []string {
	if len(s) == 0 {
		return []string{}
	}

	result := make([]string, 0, len(s))
	temp := map[string]struct{}{}
	for _, item := range s {
		if _, ok := temp[item]; !ok {
			temp[item] = struct{}{}
			result = append(result, item)
		}
	}
	return result
}

func RemoveReIntData(s []int) []int {
	if len(s) == 0 {
		return []int{}
	}

	result := make([]int, 0, len(s))
	temp := map[int]struct{}{}
	for _, item := range s {
		if _, ok := temp[item]; !ok {
			temp[item] = struct{}{}
			result = append(result, item)
		}
	}
	return result
}

// 查看是否在切片中
func InStrSlice(t string, s []string) bool {
	for _, v := range s {
		if t == v {
			return true
		}
	}
	return false
}
